﻿using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
using CodeCrawler.UI.Data;
using OWASP.CodeReview.CodeCrawler.Engine;
using OWASP.CodeReview.CodeCrawler.Engine.Exceptions;

namespace CodeCrawler.UI.Engine.KeyPointersScan {

    public static class Core {

        const string REPORTFILEEXTENSION = ".owasp" ;

        

        public static void ScanEngine(ref DataTable currentThreatListDataTable,
                                      DataSet xmlCodeCrawlerDatabase,
                                      ref DataGridView vulnGrid,
                                      string fileName) {

            if (File.Exists(fileName)) {

                TextReader re               = File.OpenText(fileName);
                string input                = null;
                int lineNumber              = 1;

                var threatCollectionList    = new ThreatCollection();
                var databaseObjects         = new CodeCrawlerXMLDatabase();

                while ((input = re.ReadLine()) != null) {
                    Threat threatObject     = threatCollectionList.ParseLineOfCode(input, xmlCodeCrawlerDatabase, lineNumber);

                    if (threatObject    != null) {
                        var collection  = new ThreatCollection();
                        collection.AddThreatItem(threatObject, currentThreatListDataTable);
                    }

                    lineNumber++;
                }

                re.Close();
                vulnGrid.DataSource         = currentThreatListDataTable;
            }


            // After reading the source code file, automatically generate a dump of the file processed.
            // This will generate a file into /Results/DumpData
            GenerateDump(currentThreatListDataTable, fileName);
        }


        public static void ScanEngine(ref DataTable currentThreatListDataTable,
                                      DataSet xmlCodeCrawlerDatabase,
                                      string fileName) {
            
            if (File.Exists(fileName)) {
                TextReader re       = File.OpenText(fileName);
                string input        = null;
                int lineNumber      = 1;

                var threatCollectionList    = new ThreatCollection();
                var databaseObjects         = new CodeCrawlerXMLDatabase();

                while ((input = re.ReadLine()) != null) {
                    Threat threatObject = threatCollectionList.ParseLineOfCode(input, xmlCodeCrawlerDatabase, lineNumber);

                    if (threatObject    != null) {
                        var collection  = new ThreatCollection();
                        collection.AddThreatItem(threatObject, currentThreatListDataTable);
                    }

                    lineNumber++;
                }

                re.Close();
            }


            // After reading the source code file, automatically generate a dump of the file processed.
            // This will generate a file into /Results/DumpData
            GenerateDump(currentThreatListDataTable, fileName);
        }


        /// <summary>
        /// Create a Dump of the scanned file
        /// and store it into /ApplicationPath/Results/DumpData
        /// </summary>
        /// <param name="currentFileDump"></param>
        /// <param name="FileName"></param>
        private static void GenerateDump(DataTable currentFileDump, string FileName) {
            string generatedDumpFolderPath = string.Concat(Application.StartupPath, "/Results/DumpsData/");

            // Check if folder is exists
            var generatedDumpFolderInfo     = new DirectoryInfo(generatedDumpFolderPath);
            if (!generatedDumpFolderInfo.Exists) {
                // Folder doesn't exists, create.
                generatedDumpFolderInfo.Create();
            }

            // Assume creating dump folder won't be a problem, the folder IO has been checked.
            var currentFileInfo             = new FileInfo(FileName);

            if (currentFileInfo.Exists) {
                // This may look like huge, but in order to avoid duplicates 
                // additional informations need to be attached to the file name
                // DumpFile Structure
                // - currentFileName (MySourceCodeFile [without.cs])
                //                  - Month
                //                  - Day
                //                  - Year
                //                  - Hours
                //                  - Minutes
                //                           - .xml
                currentFileDump.WriteXml(string.Concat(generatedDumpFolderPath, currentFileInfo.Name,
                                                       DateTime.Now.Month.ToString(), DateTime.Now.Day.ToString(),
                                                       DateTime.Now.Year.ToString(), DateTime.Now.Hour.ToString(),
                                                       DateTime.Now.Minute.ToString(), REPORTFILEEXTENSION));
            }
            else {
                // Unable to retrieve source code file name. File doesn't exists
                throw new SourceCodeFileDoesntExistAnyMoreException();
            }
        }
    }
}